<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>原型，继承</title>
</head>
<body>
<script>
    /*
    * 对JS原型的重新认知
    *   JS的原型对象不是对象的_proto_或者构造函数的prototype 这两个不过是修改[[prototype]]的函数
    *   JS的原型本质上依靠的是[[prototype]]的指向
    *    设置对象的_proto_属性是将对象的[[prototype]]指向该设置的对象
    *    设置构造函数的prototype属性是将该构造函数创建出来的对象的[[prototype]]设置为那个对象
    *
    *
    * */

    function Obj() {
        this.age = 23
    }

    Obj.prototype = {
        username: 'Alice',
        constructor: Obj
    }


    let obj = new Obj()
    console.log(obj.username)


    /*
    * 这里重新设置构造函数的prototype属性会影响再次使用 new Obj()创建出来的对象的[[prototype]]指向
    *
    *  而上面创建出来的obj对象依旧可以通过隐藏属性[[prototype]]访问到之前的对象
    *
    *   let a = {}
    *   a= {}
    *
    * 上面a重新指向了那么之前的那个对象就会被垃圾回收
    * 而我们这里将对象的原型指向新的对象之前原型指向的那个对象不被回收的原因在于被之前的实例化对象的隐藏属性[[prototype]]指向
    * 这有点像闭包 如果想让他回收的话直接将之前的实例化对象=null就行
    *
    * */
    Obj.prototype = {
        username: 'jack'
    }

    /*
    * 但这样修改的话就会影响到了 就算在创建对象之后再设置原型上的属性也会影响使用那个对象还是可以访问到
    * 因为属性的读取是松散的
    * */
    // Obj.prototype.username ="bhbhsd"

    /*新创建的对象的[[prototype]]会被影响*/
    let obj1 = new Obj()
    console.log(obj1.username)

    console.log(obj.username)

    // let prototype = {
    //     name: '1'
    // }
    //
    // let a ='[[prototype]]'
    //
    // [a] =prototype
    //
    // prototype ={
    //
    // }


    /*
      原型必须是对象 所以下面这样写没有意义


    function  Animal(){

        }
        Animal.prototype = 1*/


</script>
</body>
</html>